项目教程 | 有了这个AI热成像仪,户外露营很安全
这不,来自美国的创客Mithun Das就用Wio Terminal和Grove MLX90640 红外热像仪模块制作了一个“露营伴侣”,顺带还上了一下《无线电》杂志4月刊。接下来就跟柴火菌开启这个有趣的项目之旅吧!
无线电杂志刊登
创作不易,开源即爱!点赞、转发、在看、留言支持创作者哟,超详细教程附上:
作|者|介|绍
Mithun Das
Cox Automotive 杰出工程师 | Edge Impulse & Balena 大使
我喜欢露营,通常每年我会和家人一起露营1-2次,这个频率绝对算不上是一个露营狂热爱好者。但对于许多野营爱好者来说,在森林深处露营是常有的事儿。在森林深处露营是一种冒险,但也会常遇到熊、土狼等野生动物的威胁。
目前市面上是有用相机来追踪野生动物的设备方案,但问题是,一般相机无法在黑暗中正常工作。这也是为什么野生动物袭击露营者的事件大多发生在夜间的原因。
那么这事儿有解决方案吗?还真有!如果有一款可以在黑暗中运行并在任何野生动物接近营地时提醒露营者的设备,这个问题就迎刃而解而解了。
普通相机肯定没办法达到这个要求,但热像仪却可以,因为它可以在没有光的情况下,依然可以正常检测。
我的解决方案就是我做的这个露营伴侣设备。我应用了矽递科技研发的Wio Terminal和Grove MLX90640 红外热像仪模块来搭建,并最终在Wio Terminal上运行tinyML微型机器学习模型来预测是否有动物或其他人类接近。
如果检测到有动物或人靠近,数据将发送到Helium网络,并通过AWS提醒露营者潜在的危险。
Seeed矽递科技Wio Terminal×1
Seeed矽递科技 Wio Terminal LoRaWAN机箱(自带天线,内置 LoRa-E5 和 GNSS)×1
Seeed矽递科技 Wio Terminal电池盒 (650mAh)×1
Seeed矽递科技Grove热像仪/红外阵列模块(MLX90640 110 度) ×1
Helium LoRaWAN Hotspot (非必选,如果项目部署所在地没有网络覆盖,则需要该设备)×1
Arduino IDE
Edge Impulse在线模型训练平台
亚马逊云物联网设备连接平台AWS IoT
3D打印机
关于微型机器学习模型这块,我使用的是Edge Impulse Studio来构建这个项目的机器学习模型。在我做这个项目时(2021年11月),Edge Impulse Studio暂时还不支持直接采集热像仪数据。
因此我使用了Wio Terminal来收集数据后,再将数据转发到Edge Impulse来创建模型。这个数据采集做法,我借鉴了一位日本创客 Naveen在他一个项目中的做法。
首先在Edge Impulse官网注册好个人账号(对个人用户免费),然后前往登录你的个人账号,并在里面点击“创建新项目”。项目创建号之后,请点击“Keys密钥”选项卡,在里面找到并点击“添加HMACkey”选项。将这个HMACkey密钥复制保存起来,后面将会用到这个资料。
项目中所用到的红外热像仪模块搭载的是一个32x24阵列的热敏传感器MLX90640,它可检测到位于1英尺(0.3048米)外的物体的温度,精度为±1.5 ℃。
为了更方便获取红外热图像,我用了I2C协议从相机获取低分辨率图像。图像的数据是一个32x24的数组,即768个温度值。MLX90640传感器通过I2C端口连接到Wio Terminal,我在WioTerminal插了一个SD卡来存储CSV文件中的读数。Wio Terminal自带的3个按钮被我用来标记以下3个数据类别:
按钮A- Animal动物,按钮B-Human人类,按钮C- Background背景
本项目用到的程序已经开源分享,大家可以在“柴火创客空间”公众号后台回复“露营伴侣”下载附件,使用WIO_Camper_Data_Collector.ino程序用来收集数据。大家下载程序后,将程序上传到 Wio Terminal,就可以开始收集数据了。
完成数据采集后,我们从 Wio Terminal中取出Micro SD卡并插入计算机,就可以获得上图的CSV文件,每个文件都有768个以逗号分隔的值(见下图)。
在data文件夹中找到名为raw的目录,然后将上方的所有CVS文件都复制到这个目录中。随后运行imager.py这个程序,这个程序会在这个/data/visual这个文件夹中创建一个数据的可视化呈现(如下图)。
此步骤为非必选,也跟后面的模型训练没有直接关系,但它可以帮助我们以图像可视化的形式直观看到所有csv数据。
这是一个非常有趣的步骤。目前Edge Impulse数据转发器只能支持转发以时间序列排序的原始数据。但热像仪的数据是非时间序列的。
相反,它是一个32x24的数组,其中包含768个离散值。所以,要进行数据转发的话,我们要将其视为单通道中间隔1毫秒的768个时间序列数据。这样说有点抽象,下面这张图会更直观展示我所说的意思。
上图就可以看到,每一张图像中所代表的768个值,变成了间隔为1毫秒的时间序列数据。下一步在将数据上传到Edge Impulse之前,就需要将这些数据进行格式化。
打开data-formatter.py并粘贴之前我们复制的HMACKey密钥。然后运行程序。
这个程序将为每个cvs文件创建一个json文件,并将它们存储在/data/formatted_data文件夹中。而且你也可以从下面的程序截图中看到数值已经变成以1秒为间隔的时间序列数据了。唯一的传感器数据通道代表的就是温度数值。
当我们准备好数据之后,我们就要用Edge Impulse CLI工具来上传数据。上传之前,我们需要安装好CLI。
通过CD改变目录命令进入formatted_data文件夹,然后执行以下命令。
edge-impulse-uploader--category split *.json
这个命令会将所有json数据上传到我们前面创建的Edge Impulse 项目中的“数据采集”页面。
现在我们收集好了数据,就可以在Edge Impulse上创建和训练我们的模型了。前往“创建冲动”页面。
单击“添加输入块Addan input block”,选择“时间序列数据Timeseries data”。将窗口大小和窗口增加大小都设置为768毫秒。这样设置的原因是要跟我们的json数据中间隔为1毫秒的768个值进行对应。
接下来,单击“添加处理块Adda processing block”,选择“原始数据Rawdata”。
然后,点击“添加学习块Adda learning block”,选择Keras分类Classification并点击“保存脉冲SaveImpulse”按钮。
然后在左侧,Create Impulse下面,点击前往“原始数据RawData”页面,保留页面上的默认值并点击“NN分类器NNClassifier”,转到训练配置页面,在这个页面设置模型训练周期和学习率。完成后点击Starttraining开始训练模型,等待模型训练完毕。
模型训练完毕后,在右侧转到Modeltesting,导入一个上升序列的CSV文件或者下降序列的CSV文件进行模型测试,注意导入的CSV序列不可与之前导入的作为训练的序列相同。测试后观察测试结果:
模型表现性能一定要尽可能好。如果模型表现不佳,我们就要收集更多数据并重新训练新的模型。
在Edge Impulse上前往“部署”页面,选择“Arduino”选项。这一操作会将模型以Arduino库的形式下载为zip文件。将这个库导入Arduino IDE。如果 你的项目名称也是用“camper”,那么你的库文件应该是camper_inferencing.h
一开始做这个项目原型的时候,我是通过WiFi连接向AWSIoT发送监测数据。首先要让Wio Terminal连接WiFi,这是先要更新它的设备固件。更新过程非常简单,参考Seeed Wiki官方教程进行即可.
而要连接到AWS,我们还需要创建一个“事物Thing”并使用证书连接到创建的“事物Thing”。矽递科技官方GitHub账号提供了一个实用的Python程序。
(点击此处查看下载:https://github.com/Seeed-Studio/Seeed_Arduino_rpcAWS/tree/master/tools/create_thing),内含这个步骤所需要的所有资源。
我在我的另一个项目教程中,也详细解释了AWS的设置,你也可以参考这个项目教程来进行相应的操作(https://www.hackster.io/mithun-das/scale-your-fleet-of-tinyml-solutions-680041)。
矽递科技的这个create_thing.py程序将在terminal上输出证书和私钥。复制它们并粘贴到cogfig.h文件中。
此外,我们还需要输入我们的WiFi凭证和AWSIoT的主机地址。修改完成后,将WIO_Camper_Inference.ino程序上传到Wio Terminal即完成了所有设置。
到此,这个露营伴侣设备将会每分钟向AWSIoT 主题发送数据,当其检测到动物或人类靠近时,露营伴侣设备会通过Wio Terminal自带的蜂鸣器发出警报声,实现野外露营夜间的安全守护。
下面这张图片是我在家用我家狗子做的一个简单测试(我家附近没有其他更适合的模特,正好抓到它在睡觉就让它上了)。后续我也会前往家附近的动物园来进一步测试下设备和模型的精准度。
由于数据已经同步到AWS中,其实我们就可以做更多有趣的延伸,例如:将数据发送到dynamodb,运行一些分析,或者使用Amazon Pinpoint向移动设备发送推送通知,向我们的手机发送短信通知等等。
项目原型基本实现之后,我对这个项目也做了全面的复盘。因为主要的项目应用场景定义为野外露营,所以项目原型阶段依赖的WiFi就显得不太适用(毕竟基本野外是没有WiFi的嘛)。
所以,我对项目的未来规划和改进主要会围绕下面两点进行:
1)或许可以开发一个app,通过蓝牙连接到Wio Terminal并将数据发送到app,这样Wio Terminal就不需直接向AWS发送数据。然后,app可以通过cognito将数据发送到AWS,这样就可以解决依靠WiFi传输数据的缺点。这样的方法,我在我的另一个项目(Buddy,项目链接:https://www.hackster.io/mithun-das/buddy-a-personal-home-office-assistance-77b2d2)中也有过尝试,可靠性比较高。
2)可能一个更好的方案就是完全断掉对wifi或蜂窝网络的依赖,让设备直接通过LoRa网络(TTN或Helium)发送数据。然后,TTN或Helium会将消息委托给AWSIoT。这个方案,我以前的几个项目中也用到过,也是可行的。下面的教程,我就会带着大家应用LoRa网络协议的Helium来接入,并与AWS连接。
所以跟据上面的改良方向,我做了第二版改良设计最终的成果如下图所示:
Helium是一个为低能耗物联网设备能与互联网连接互通所建立的点对点无线网络,它主要通过LoRaWAN网关,支持LoRaWAN协议的物联网设备提供公共的无线网络覆盖,使物联网设备更方便地接入互联网和传输数据。
这个网络最近的覆盖率增长极快,覆盖范围也很广,对于户外露营来说,这是一个很不错的选择。
首先硬件部分要记得将Wio Terminal LoRaWAN机箱中自带的天线按照官方指南装上,热像仪/红外阵列模块则通过I2C端口与Wio Terminal电池盒相连,随后将伺服电机连接到Wio Terminal电池盒的数字引脚0。
然后将电池盒放置在Wio Terminal LoRaWAN机箱顶部,再将Wio Terminal放置在电池盒的顶部(如下图所示)。
随后将这个代码:
WIO_Camper_Inference_lora.ino上传到Wio-Terminal中。
在继续下一步之前,这些基础知识我们需要先了解下,因为我们可能需要根据各自实际情况相应修改上方提及的代码。
LoRaWAN是一种建立在LoRa无线电调制技术之上的低功耗、广域的网络协议。它将物联网设备以无线的方式连接到互联网,并能对终端节点设备和网络网关之间的通信进行管理。
每个国家/地区都有特定的频段和数据速率(DR)。而根据各地的数据速率DR,最大数据有效负载大小会有所不同。在我的代码中,我所在地的频段是US915,但用的数据速率为DR0(实际为DR2 ),它的最大有效载荷大小为11个字节。
理想情况下,DR2 可以在Helium中使用,但因为我没把Wio Terminal机箱调通为DR2 ,所以就用了DR0代替,但这并不影响,因为其有效负载大小为10字节(够用了)。
E5_Module_Cmd_tE5_Module_Cmd[]={
{"+AT:OK",1000,"AT\r\n"},
{"+ID:AppEui",1000,"AT+ID\r\n"},
{"+MODE",1000,"AT+MODE=LWOTAA\r\n"},
{"+DR",1000,"AT+DR=US915\r\n"},
//{"+RATE",1000,"AT+DR=0\r\n"},
{"CH",1000,"AT+CH=NUM,8-15\r\n"},
{"+KEY:APPKEY",1000,"AT+KEY=APPKEY,\"2B7E151628AED2A6ABF7158809CF4F3C\"\r\n"},
{"+CLASS",1000,"AT+CLASS=A\r\n"},
{"+ADR",1000,"AT+ADR=OFF\r\n"},
{"+PORT",1000,"AT+PORT=2\r\n"},
//{"+LW",1000,"AT+LW=LEN\r\n"},
{"Done",10000,"AT+JOIN\r\n"},
{"Done",30000,""},
};
如果你所在地区不再北美,那么使用这段代码时,就需要相应修改其中的频段、频道和端口。具体地区对应的数据设置,可以参考这个链接(https://docplayer.net/98433344-Lorawan-class-a-c-at-command-specification-lorawan-at-command-uart-usb-this-document-defines-at-command-format-used-by-risinghf-lorawan-module.html)。
接下来,我们需要在Helium控制台(链接:https://console.helium.com/)上创建一个帐户,用来注册我们的设备。此外,我们还需要DataCredits(用于发送数据)。进入控制台后,导航到设备页面并添加新设备。
我们需要DevEUI、AppEUI 和AppKey。在Wio Terminal上,将蓝色按钮向左滑动并按住,直到出现设备信息。在Helium控制台上的设备中输入此信息。如果你的Wio Terminal仍然连接到Arduino IDE,设备信息也会打印在串行控制台上,因此我们也可以从那里复制/粘贴。
欢迎按照这个链接(https://docs.helium.com/use-the-network/console/adding-devices/)获取详细说明。注册设备后,我们就需要创建一个标签。
接下来,我们需要创建一个函数。前往Functions函数页面,输入名称并选择“自定义脚本”。然后粘贴下面的javascript代码并保存。
此时,你应该会在Helium实时数据部分看到来自你的设备数据,如下所示。请注意,有效负载大小为10个字节。任何长达24字节的数据包都将消耗1个DataCreadit。
按照Helium官方网站提供的教程进行AWSIoT集成即可(https://docs.helium.com/use-the-network/console/integrations/aws-iot-core/)。
集成完成后,前往访问Helium控制台的Flows页面并参考上图创建一个工作流程。这个工作流程基本上将你的设备标签连接到aws集成并应用自定义脚本来解密base64 编码字符串。
现在你需要创建一个lambda函数。你可以在我的lambda文件夹下的repo中找到lambda代码。为了便于部署,我提供了一个deploy.sh文件,它将从命令行直接部署python代码。
你只需要先配置awscli,然后就可以运行。这个步骤教程较为简略,相信大家都有aws的基本知识,所以我这里会跳过配置步骤。请注意,你需要拥有Telegram机器人访问token和聊天ID。
这个步骤的设置,可以参考这个项目(https://www.hackster.io/mithun-das/smart-bird-feeder-powered-by-edge-impulse-and-balena-fin-bd6416#toc-setup-telegram-bot-3)设置Telegram机器人并获取机器人token和聊天ID。
部署lambda后,转到AWSIoT Core并创建规则。使用你在helium控制台上使用的主题名称,并在“操作”页面下,选择你刚刚部署的lambda函数。
现在你可以试着将热像仪放在人或动物面前,这时你在手机上就会收到通知以及GPS位置。
再接下来,大家就可以按照我提供的3d文件打印设备外壳了。当然,也欢迎大家发挥创意,自行设计哟。
3d打印外壳视频
为了进一步改进这个项目,我给Wio Terminal设计了一个太阳能底盘。它带有一个1100mAh电池和一个尺寸为110mmx 69mm的太阳能电池板(5V、250mA )。这样一来,这个露营伴侣设备充电就可以更加方便和便捷了。
你都看到这里了,不打算自己也来复刻一个吗?关于这个项目,你有何感想,评论区等你来!
更多Wio Terminal项目教程:
人才升级 推动双创事业合作
----END---- Chaihuo x.factory|深圳,河北